﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.Revit
{
	public class YJKPiping<T> where T : MEPCurve
	{
		public YJKPiping(T piping)
		{
			this.piping = piping;
			this.isSeparate = false;
			this.InitCustomConnector(piping);
		}

		public YJKPiping(T piping, XYZ globalPoint)
		{
			this.piping = piping;
			this.isSeparate = false;
			this.globalPoint = globalPoint;
			this.InitCustomConnector(piping);
		}

		private void InitCustomConnector(T piping)
		{
			this.sideConnector = new List<Connector>();
			IList<HYConnector> list = new List<HYConnector>();
			ConnectorSetIterator connectorSetIterator = piping.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (1 == connector.ConnectorType)
				{
					list.Add(new HYConnector(connector));
				}
				else if (2 == connector.ConnectorType)
				{
					this.sideConnector.Add(connector);
				}
			}
			this.startConnector = list.ElementAt(0);
			this.endConnector = list.ElementAt(1);
			this.shape = this.startConnector.Connector.Shape;
			if (Math.Abs(this.startConnector.Origin.Z - this.endConnector.Origin.Z) < 0.0001)
			{
				this.pipingPositionType = 0;
				return;
			}
			if (Math.Abs(this.startConnector.Origin.X - this.endConnector.Origin.X) < 0.0001 && Math.Abs(this.startConnector.Origin.Y - this.endConnector.Origin.Y) < 0.0001)
			{
				this.pipingPositionType = 1;
				return;
			}
			this.pipingPositionType = 2;
		}

		public Connector GetCloseConnector(XYZ xyzIntersection, bool beFar = false)
		{
			Connector result;
			if (beFar)
			{
				result = ((YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin) > YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin)) ? this.startConnector.Connector : this.endConnector.Connector);
			}
			else
			{
				result = ((YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin)) ? this.startConnector.Connector : this.endConnector.Connector);
			}
			return result;
		}

		public bool BeMiddlePointDuct()
		{
			XYZ xyz = this.GlobalPoint;
			if (xyz == null)
			{
				return true;
			}
			double num = this.StartConnector.Origin.DistanceTo(xyz);
			double num2 = this.EndConnector.Origin.DistanceTo(xyz);
			return Math.Abs(num - num2) < 0.00984251968503937;
		}

		public Connector GetNearConnectorToPoint(XYZ xyzIntersection)
		{
			double num = YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin);
			double num2 = YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin);
			if (num >= num2)
			{
				return this.endConnector.Connector;
			}
			return this.startConnector.Connector;
		}

		public Connector GetAppropriateConnector(XYZ xyzIntersection)
		{
			Connector result = null;
			if (this.IsPointOnPipingCurveExtension(xyzIntersection))
			{
				result = ((YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin)) ? this.startConnector.Connector : this.endConnector.Connector);
			}
			else if (this.IsPointOnPipingCurve(xyzIntersection))
			{
				if (this.globalPoint != null)
				{
					double num = Math.Abs(YJKRevitTools.DistanceTwoXYZ(this.globalPoint, xyzIntersection) + YJKRevitTools.DistanceTwoXYZ(this.globalPoint, this.startConnector.Origin) - YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin));
					double num2 = Math.Abs(YJKRevitTools.DistanceTwoXYZ(this.globalPoint, xyzIntersection) + YJKRevitTools.DistanceTwoXYZ(this.globalPoint, this.endConnector.Origin) - YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin));
					result = ((num > num2) ? this.startConnector.Connector : this.endConnector.Connector);
				}
				else
				{
					result = ((YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.startConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(xyzIntersection, this.endConnector.Origin)) ? this.startConnector.Connector : this.endConnector.Connector);
				}
			}
			return result;
		}

		public int CheckConnLocation(Connector conn1, Connector conn2)
		{
			if (conn1 == null || conn2 == null)
			{
				return -2;
			}
			XYZ basisZ = conn1.CoordinateSystem.BasisZ;
			XYZ basisZ2 = conn2.CoordinateSystem.BasisZ;
			if (!basisZ.IsAlmostEqualTo(-1.0 * basisZ2, 0.001))
			{
				return -1;
			}
			XYZ origin = conn1.Origin;
			XYZ xyz = conn2.Origin.Subtract(origin).Normalize();
			double num = basisZ.AngleTo(xyz);
			if (num < 0.0001 || Math.Abs(num - Math.PI) < 0.0001)
			{
				return 1;
			}
			return 0;
		}

		public int CheckDuctsRelation(Duct duct1, Duct duct2)
		{
			if (duct1 == null || duct2 == null)
			{
				return -1;
			}
			double num = duct1.get_Parameter(BuiltInParameter.RBS_DUCT_TOP_ELEVATION).AsDouble();
			double num2 = duct1.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble();
			double num3 = duct1.get_Parameter(BuiltInParameter.RBS_DUCT_BOTTOM_ELEVATION).AsDouble();
			double num4 = duct2.get_Parameter(BuiltInParameter.RBS_DUCT_TOP_ELEVATION).AsDouble();
			double num5 = duct2.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble();
			double num6 = duct2.get_Parameter(BuiltInParameter.RBS_DUCT_BOTTOM_ELEVATION).AsDouble();
			if (Math.Abs(num2 - num5) < 0.005)
			{
				return 1;
			}
			if (Math.Abs(num - num4) < 0.005)
			{
				return 0;
			}
			if (Math.Abs(num3 - num6) < 0.005)
			{
				return 2;
			}
			return -2;
		}

		public bool IsPointOnPipingCurveExtension(XYZ xyz)
		{
			bool result = false;
			if (Math.Abs(Math.Abs(YJKRevitTools.DistanceTwoXYZ(xyz, this.startConnector.Origin) - YJKRevitTools.DistanceTwoXYZ(xyz, this.endConnector.Origin)) - YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, this.endConnector.Origin)) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnPipingCurve(XYZ xyz)
		{
			bool result = false;
			if (Math.Abs(YJKRevitTools.DistanceTwoXYZ(xyz, this.startConnector.Origin) + YJKRevitTools.DistanceTwoXYZ(xyz, this.endConnector.Origin) - YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, this.endConnector.Origin)) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public IList<Connector> GetAppropriateConnector(T othePiping)
		{
			IList<Connector> list = new List<Connector>();
			YJKPiping<T> hypiping = new YJKPiping<T>(othePiping);
			if (YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, hypiping.StartConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, hypiping.EndConnector.Origin))
			{
				if (YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, hypiping.StartConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(this.endConnector.Origin, hypiping.StartConnector.Origin))
				{
					list.Add(this.startConnector.Connector);
					list.Add(hypiping.StartConnector.Connector);
				}
				else
				{
					list.Add(this.endConnector.Connector);
					list.Add(hypiping.StartConnector.Connector);
				}
			}
			else if (YJKRevitTools.DistanceTwoXYZ(this.startConnector.Origin, hypiping.EndConnector.Origin) < YJKRevitTools.DistanceTwoXYZ(this.endConnector.Origin, hypiping.EndConnector.Origin))
			{
				list.Add(this.startConnector.Connector);
				list.Add(hypiping.EndConnector.Connector);
			}
			else
			{
				list.Add(this.endConnector.Connector);
				list.Add(hypiping.EndConnector.Connector);
			}
			return list;
		}

		public int PipingPositionType
		{
			get
			{
				return this.pipingPositionType;
			}
		}

		public XYZ GlobalPoint
		{
			get
			{
				return this.globalPoint;
			}
			set
			{
				this.globalPoint = value;
			}
		}

		public HYConnector StartConnector
		{
			get
			{
				return this.startConnector;
			}
		}

		public HYConnector EndConnector
		{
			get
			{
				return this.endConnector;
			}
		}

		public bool IsSeparate
		{
			get
			{
				return this.isSeparate;
			}
		}

		public ConnectorProfileType Shape
		{
			get
			{
				return this.shape;
			}
		}

		public bool IsPipingOnLine(T otherPiping)
		{
			bool result = false;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			if (this.IsPointOnPipingLine(hypiping.StartConnector.Origin) && this.IsPointOnPipingLine(hypiping.EndConnector.Origin))
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnPipingLine(XYZ xyz)
		{
			bool result = false;
			if (this.IsPointOnPipingCurve(xyz) || this.IsPointOnPipingCurveExtension(xyz))
			{
				result = true;
			}
			return result;
		}

		public bool IsPointOnPipingCurve(XYZ xyz, double deviation)
		{
			bool result = false;
			if (Math.Abs(xyz.DistanceTo(this.StartConnector.Origin) + xyz.DistanceTo(this.EndConnector.Origin) - this.StartConnector.Origin.DistanceTo(this.EndConnector.Origin)) < 0.0001 && xyz.DistanceTo(this.StartConnector.Origin) > deviation && xyz.DistanceTo(this.EndConnector.Origin) > deviation)
			{
				result = true;
			}
			return result;
		}

		public bool IsIntersection(T otherPiping)
		{
			bool result = false;
			if (this.IntersectionPoint(otherPiping) != null)
			{
				result = true;
			}
			return result;
		}

		public bool BeRotateDuct(Duct newDuct)
		{
			YJKPiping<Duct> hypiping = new YJKPiping<Duct>(newDuct);
			if (this.Shape != 1 || !YJKRevitTools.IsRiserDuct(newDuct))
			{
				return false;
			}
			double weightOrDiameter = this.GetWeightOrDiameter();
			double heightOrDiameter = this.GetHeightOrDiameter();
			if (Math.Abs(weightOrDiameter - heightOrDiameter) < 0.0032808398950131233)
			{
				return false;
			}
			bool widthMax = weightOrDiameter > heightOrDiameter;
			YJKLine ductWidthLine = this.GetDuctWidthLine(this.Piping as Duct, widthMax);
			YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
			XYZ basisX = hypiping.StartConnector.Connector.CoordinateSystem.BasisX;
			hyrotateFamilyInstance.MoveElement(basisX, newDuct);
			hyrotateFamilyInstance.MoveElement(-1.0 * basisX, newDuct);
			this.Piping.Document.Regenerate();
			YJKLine ductWidthLine2 = this.GetDuctWidthLine(newDuct, widthMax);
			return ductWidthLine == null || ductWidthLine2 == null || !ductWidthLine.IsParallel(ductWidthLine2.Line);
		}

		public bool BeRotateDuct(FamilyInstance terminal)
		{
			if (this.Shape != 1 || !YJKRevitTools.IsRiserDuct(this.Piping as Duct))
			{
				return false;
			}
			Connector elementConnector = YJKRevitTools.GetElementConnector(terminal);
			if (elementConnector.Shape != 1)
			{
				return false;
			}
			if (Math.Abs(elementConnector.Width - elementConnector.Height) < 0.0032808398950131233)
			{
				return false;
			}
			bool widthMax = elementConnector.Width > elementConnector.Height;
			YJKLine terminalWidthLine = this.GetTerminalWidthLine(terminal, widthMax);
			YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
			XYZ basisX = this.StartConnector.Connector.CoordinateSystem.BasisX;
			Duct duct = this.Piping as Duct;
			hyrotateFamilyInstance.MoveElement(basisX, duct);
			hyrotateFamilyInstance.MoveElement(-1.0 * basisX, duct);
			this.Piping.Document.Regenerate();
			YJKLine ductWidthLine = this.GetDuctWidthLine(duct, widthMax);
			return terminalWidthLine == null || ductWidthLine == null || !terminalWidthLine.IsParallel(ductWidthLine.Line);
		}

		private YJKLine GetTerminalWidthLine(FamilyInstance terminal, bool widthMax)
		{
			YJKLine result = null;
			IList<PlanarFace> familyInstanceSurface = UnifiedModified.GetFamilyInstanceSurface(terminal.Document, terminal);
			Connector elementConnector = YJKRevitTools.GetElementConnector(terminal);
			PlanarFace planarFace = null;
			if (familyInstanceSurface.Count <= 1)
			{
				return result;
			}
			foreach (PlanarFace planarFace2 in familyInstanceSurface)
			{
				if (planarFace2.Origin.IsAlmostEqualTo(elementConnector.Origin, 0.0001))
				{
					planarFace = planarFace2;
					break;
				}
			}
			if (planarFace == null)
			{
				return result;
			}
			Edge edge = null;
			double num = 0.0;
			foreach (object obj in planarFace.EdgeLoops)
			{
				EdgeArray edgeArray = (EdgeArray)obj;
				if (edgeArray.Size >= 1)
				{
					Edge edge2 = edgeArray[0];
					if (edge == null)
					{
						edge = edge2;
						num = edge2.ApproximateLength;
					}
					else if (widthMax)
					{
						if (edge2.ApproximateLength > num)
						{
							edge = edge2;
							num = edge2.ApproximateLength;
						}
					}
					else if (edge2.ApproximateLength < num)
					{
						edge = edge2;
						num = edge2.ApproximateLength;
					}
				}
			}
			if (edge != null)
			{
				Curve curve = edge.AsCurve();
				result = new YJKLine(curve.GetEndPoint(0), curve.GetEndPoint(1));
			}
			return result;
		}

		private YJKLine GetDuctWidthLine(Duct duct, bool widthMax)
		{
			YJKLine result = null;
			YJKPiping<Duct> hypiping = new YJKPiping<Duct>(duct);
			IList<PlanarFace> ductSurface = UnifiedModified.GetDuctSurface(duct);
			PlanarFace planarFace = null;
			XYZ basisZ = hypiping.StartConnector.Connector.CoordinateSystem.BasisZ;
			if (ductSurface.Count <= 1)
			{
				return result;
			}
			foreach (PlanarFace planarFace2 in ductSurface)
			{
				if (planarFace2.FaceNormal().IsAlmostEqualTo(basisZ, 0.0001))
				{
					planarFace = planarFace2;
					break;
				}
			}
			Edge edge = null;
			double num = 0.0;
			foreach (object obj in planarFace.EdgeLoops)
			{
				EdgeArray edgeArray = (EdgeArray)obj;
				if (edgeArray.Size >= 1)
				{
					Edge edge2 = edgeArray[0];
					if (edge == null)
					{
						edge = edge2;
						num = edge2.ApproximateLength;
					}
					else if (widthMax)
					{
						if (edge2.ApproximateLength > num)
						{
							edge = edge2;
							num = edge2.ApproximateLength;
						}
					}
					else if (edge2.ApproximateLength < num)
					{
						edge = edge2;
						num = edge2.ApproximateLength;
					}
				}
			}
			if (edge != null)
			{
				Curve curve = edge.AsCurve();
				result = new YJKLine(curve.GetEndPoint(0), curve.GetEndPoint(1));
			}
			return result;
		}

		public XYZ IntersectionPoint(T pipingOther, bool deviation)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(pipingOther);
			XYZ project = hypiping.GetProject(this.startConnector.Origin, true);
			XYZ project2 = hypiping.GetProject(this.endConnector.Origin, true);
			if (project.DistanceTo(this.startConnector.Origin) >= project2.DistanceTo(this.endConnector.Origin))
			{
				return project2;
			}
			return project;
		}

		public XYZ IntersectionPoint(T pipingOther, int deviation)
		{
			XYZ result = null;
			YJKPiping<T> hypiping = new YJKPiping<T>(pipingOther);
			YJKLine xyproject = hypiping.GetXYProject();
			XYZ xyz = this.GetXYProject().IntersectionPoint(xyproject.Line, true);
			if (xyz != null && Math.Abs(this.startConnector.Origin.Z - hypiping.StartConnector.Origin.Z) <= (double)deviation)
			{
				result = new XYZ(xyz.X, xyz.Y, this.startConnector.Origin.Z);
			}
			return result;
		}

		public XYZ IntersectionPoint(T pipingOther, double deviation)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(pipingOther);
			XYZ dlineP = YJKRevitTools.GetDLineP(this.startConnector.Origin, this.endConnector.Origin, hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			XYZ dlineP2 = YJKRevitTools.GetDLineP(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin, this.startConnector.Origin, this.endConnector.Origin);
			if (dlineP.DistanceTo(dlineP2) <= deviation)
			{
				return dlineP2;
			}
			return null;
		}

		public XYZ IntersectionPoint(T pipingOther)
		{
			XYZ result = null;
			LocationCurve locationCurve = this.piping.Location as LocationCurve;
			LocationCurve locationCurve2 = pipingOther.Location as LocationCurve;
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			Line line = YJKLineEx.YJKGetBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
			Curve curve = YJKLineEx.YJKGetBound(locationCurve2.Curve.GetEndPoint(0), locationCurve2.Curve.GetEndPoint(1));
			line.MakeUnbound();
			curve.MakeUnbound();
			SetComparisonResult setComparisonResult = line.Intersect(curve, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		public XYZ IntersectionPoint(bool beOnPipe, T pipingOther)
		{
			XYZ result = null;
			LocationCurve locationCurve = this.piping.Location as LocationCurve;
			LocationCurve locationCurve2 = pipingOther.Location as LocationCurve;
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			Curve curve = YJKLineEx.YJKGetBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
			Curve curve2 = YJKLineEx.YJKGetBound(locationCurve2.Curve.GetEndPoint(0), locationCurve2.Curve.GetEndPoint(1));
			if (!beOnPipe)
			{
				curve.MakeUnbound();
				curve2.MakeUnbound();
			}
			else
			{
				curve2.MakeUnbound();
			}
			SetComparisonResult setComparisonResult = curve.Intersect(curve2, out intersectionResultArray);
			if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		private void ChangePiping(T newPiping)
		{
			this.piping = newPiping;
			this.InitCustomConnector(this.piping);
		}

		public List<T> Separate(XYZ xyz)
		{
			List<T> list = new List<T>();
			if (!this.IsPointOnPipingCurve(xyz))
			{
				return null;
			}
			Autodesk.Revit.DB.Document document = this.piping.Document;
			HYDocument hydocument = new HYDocument(document);
			SubTransaction subTransaction = new SubTransaction(document);
			List<T> result;
			try
			{
				subTransaction.Start();
				ICollection<ElementId> collection = ElementTransformUtils.CopyElement(document, this.piping.Id, new XYZ(0.0, 0.0, 0.0));
				document.Regenerate();
				ICollection<ElementId> collection2 = ElementTransformUtils.CopyElement(document, this.piping.Id, new XYZ(0.0, 0.0, 0.0));
				document.Regenerate();
				T t = default(T);
				T t2 = default(T);
				foreach (ElementId elementId in collection)
				{
					t = (hydocument.GetElement(elementId) as T);
				}
				foreach (ElementId elementId2 in collection2)
				{
					t2 = (hydocument.GetElement(elementId2) as T);
				}
				Line curve = YJKLineEx.YJKGetBound(this.startConnector.Origin, xyz);
				Line curve2 = YJKLineEx.YJKGetBound(xyz, this.endConnector.Origin);
				LocationCurve locationCurve = t.Location as LocationCurve;
				LocationCurve locationCurve2 = t2.Location as LocationCurve;
				locationCurve.Curve = curve;
				locationCurve2.Curve = curve2;
				this.ConnectorChange(t);
				this.ConnectorChange(t2);
				foreach (Connector connector in this.sideConnector)
				{
					document.DeleteElement(this.GetConnectConnector(connector).Owner);
				}
				T t3 = this.piping;
				this.ChangePiping(t);
				document.DeleteElement(t3);
				document.Regenerate();
				list.Add(t);
				list.Add(t2);
				subTransaction.Commit();
				result = list;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
				else
				{
					this.isSeparate = true;
				}
			}
			return result;
		}

		public List<T> SeparateHoldSelf(XYZ xyz)
		{
			List<T> list = new List<T>();
			if (!this.IsPointOnPipingCurve(xyz))
			{
				return null;
			}
			Autodesk.Revit.DB.Document document = this.piping.Document;
			HYDocument hydocument = new HYDocument(document);
			SubTransaction subTransaction = new SubTransaction(document);
			List<T> result;
			try
			{
				subTransaction.Start();
				ICollection<ElementId> collection = ElementTransformUtils.CopyElement(document, this.piping.Id, new XYZ(0.0, 0.0, 0.0));
				document.Regenerate();
				T t = default(T);
				T t2 = this.piping;
				foreach (ElementId elementId in collection)
				{
					t = (hydocument.GetElement(elementId) as T);
				}
				XYZ origin = this.startConnector.Origin;
				XYZ origin2 = this.endConnector.Origin;
				if (this.endConnector.Origin.Z > this.startConnector.Origin.Z)
				{
					origin = this.endConnector.Origin;
					origin2 = this.startConnector.Origin;
				}
				Line curve = YJKLineEx.YJKGetBound(origin2, xyz);
				Line curve2 = YJKLineEx.YJKGetBound(xyz, origin);
				(t.Location as LocationCurve).Curve = curve;
				this.ConnectorChange(t);
				(t2.Location as LocationCurve).Curve = curve2;
				foreach (Connector connector in this.sideConnector)
				{
					document.DeleteElement(this.GetConnectConnector(connector).Owner);
				}
				this.ChangePiping(t);
				document.Regenerate();
				list.Add(t);
				list.Add(t2);
				subTransaction.Commit();
				result = list;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
				else
				{
					this.isSeparate = true;
				}
			}
			return result;
		}

		private void ConnectorChange(T newPiping)
		{
			ConnectorSetIterator connectorSetIterator = newPiping.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (connector != null)
				{
					if (connector.Origin.IsAlmostEqualTo(this.startConnector.Origin))
					{
						Connector connectConnector = this.GetConnectConnector(this.startConnector.Connector);
						if (connectConnector != null)
						{
							this.startConnector.Connector.DisconnectFrom(connectConnector);
							connector.ConnectTo(connectConnector);
							break;
						}
					}
					else if (connector.Origin.IsAlmostEqualTo(this.endConnector.Origin))
					{
						Connector connectConnector = this.GetConnectConnector(this.endConnector.Connector);
						if (connectConnector != null)
						{
							this.endConnector.Connector.DisconnectFrom(connectConnector);
							connector.ConnectTo(connectConnector);
							break;
						}
					}
				}
			}
			this.SideConnectorChange(newPiping);
		}

		private void SideConnectorChange(T newPiping)
		{
			Autodesk.Revit.DB.Document document = newPiping.Document;
			YJKPiping<T> hypiping = new YJKPiping<T>(newPiping);
			foreach (Connector connector in this.sideConnector)
			{
				if (hypiping.IsPointOnPipingCurve(connector.Origin))
				{
					try
					{
						Connector sideConnectConnector = this.GetSideConnectConnector(connector);
						if (sideConnectConnector != null)
						{
							FamilyInstance familyInstance = document.Create.NewTakeoffFitting(sideConnectConnector, newPiping);
							familyInstance.Symbol = (this.GetConnectConnector(connector).Owner as FamilyInstance).Symbol;
							this.FamilyInstanceParameterConvert(this.GetConnectConnector(connector).Owner as FamilyInstance, familyInstance, document);
						}
					}
					catch (Exception)
					{
					}
				}
			}
		}

		private Connector GetSideConnectConnector(Connector connector)
		{
			Connector result = null;
			Connector connectConnector = this.GetConnectConnector(connector);
			Element owner = connectConnector.Owner;
			if (owner is FamilyInstance)
			{
				ConnectorSetIterator connectorSetIterator = (owner as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId == connectConnector.Owner.UniqueId && !connector2.Origin.IsAlmostEqualTo(connectConnector.Origin))
					{
						result = this.GetConnectConnector(connector2);
						break;
					}
				}
			}
			return result;
		}

		private Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && (connector2.ConnectorType == 1 || connector2.ConnectorType == 2 || connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		public void ParameterConvert(T sourcePiping, T newPiping, Document document)
		{
			SubTransaction subTransaction = new SubTransaction(document);
			subTransaction.Start();
			foreach (object obj in newPiping.Parameters)
			{
				Parameter parameter = (Parameter)obj;
				switch (parameter.StorageType)
				{
				case 1:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcePiping.get_Parameter(parameter.Definition).AsInteger());
					}
					break;
				case 2:
					if (!parameter.IsReadOnly && !(parameter.Definition.Name == "偏移量") && !(parameter.Definition.Name == "OffSet"))
					{
						parameter.Set(sourcePiping.get_Parameter(parameter.Definition).AsDouble());
					}
					break;
				case 3:
					if (!parameter.IsReadOnly && parameter.IsShared)
					{
						parameter.Set(sourcePiping.get_Parameter(parameter.Definition).AsString());
					}
					break;
				case 4:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcePiping.get_Parameter(parameter.Definition).AsElementId());
					}
					break;
				}
			}
			if (!new YJKPiping<T>(newPiping).IsZAxis())
			{
				Parameter parameter2 = newPiping.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM);
				parameter2.Set(sourcePiping.get_Parameter(parameter2.Definition).AsDouble());
			}
			if (subTransaction.Commit() == 5)
			{
				subTransaction.RollBack();
			}
		}

		public void FamilyInstanceParameterConvert(FamilyInstance sourcefi, FamilyInstance newfi, Document document)
		{
			SubTransaction subTransaction = new SubTransaction(document);
			subTransaction.Start();
			foreach (object obj in newfi.Parameters)
			{
				Parameter parameter = (Parameter)obj;
				switch (parameter.StorageType)
				{
				case 1:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsInteger());
					}
					break;
				case 2:
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsDouble());
					}
					break;
				case 3:
					if (!parameter.IsReadOnly && parameter.IsShared)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsString());
					}
					break;
				case 4:
					parameter.AsElementId();
					if (!parameter.IsReadOnly)
					{
						parameter.Set(sourcefi.get_Parameter(parameter.Definition).AsElementId());
					}
					break;
				}
			}
			Parameter parameter2 = newfi.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
			parameter2.Set(sourcefi.get_Parameter(parameter2.Definition).AsDouble());
			if (subTransaction.Commit() == 5)
			{
				subTransaction.RollBack();
			}
		}

		public T Piping
		{
			get
			{
				return this.piping;
			}
		}

		public Curve GetLocationCurve()
		{
			return (this.piping.Location as LocationCurve).Curve;
		}

		public bool IsVertical(T otherPiping)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			XYZ xyz = this.startConnector.Origin - this.endConnector.Origin;
			XYZ xyz2 = hypiping.EndConnector.Origin - hypiping.StartConnector.Origin;
			double num = xyz.AngleTo(xyz2);
			return Math.Abs(num - Math.PI*.5) < 0.009 || Math.Abs(num - 4.71238898038469) < 0.009;
		}

		public bool IsParallel(T otherPiping)
		{
			bool result = false;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			XYZ xyz = this.startConnector.Origin - this.endConnector.Origin;
			XYZ xyz2 = hypiping.EndConnector.Origin - hypiping.StartConnector.Origin;
			double num = xyz.AngleTo(xyz2);
			if (Math.Abs(num - Math.PI) < 0.0001 || num < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool IsXYParallel(T otherPiping)
		{
			bool result = false;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			if ((YJKRevitTools.isRiserPiping(this.piping) && !YJKRevitTools.isRiserPiping(otherPiping)) || (!YJKRevitTools.isRiserPiping(this.piping) && YJKRevitTools.isRiserPiping(otherPiping)))
			{
				return false;
			}
			XYZ xyz = new XYZ(this.endConnector.Origin.X, this.endConnector.Origin.Y, 0.0) - new XYZ(this.startConnector.Origin.X, this.startConnector.Origin.Y, 0.0);
			XYZ xyz2 = new XYZ(hypiping.EndConnector.Origin.X, hypiping.EndConnector.Origin.Y, 0.0) - new XYZ(hypiping.StartConnector.Origin.X, hypiping.StartConnector.Origin.Y, 0.0);
			double num = xyz.AngleTo(xyz2);
			if (Math.Abs(num - Math.PI) < 0.0001 || num < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public double GetDistance(T otherPiping)
		{
			double result = -1.0;
			if (this.IsParallel(otherPiping))
			{
				YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
				Line line = YJKLineEx.YJKGetBound(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
				line.MakeUnbound();
				result = line.Distance(this.startConnector.Origin);
			}
			return result;
		}

		public double GetDistanceSumEnd(XYZ point)
		{
			return this.startConnector.Origin.DistanceTo(point) + this.endConnector.Origin.DistanceTo(point);
		}

		public double GetXYDistance(T otherPiping)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			return hyline.GetXYDistance(hyline2.Line);
		}

		public double GetXYTouYingDistance(T otherPiping)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			YJKLine hyline = new YJKLine(new XYZ(this.startConnector.Origin.X, this.startConnector.Origin.Y, 0.0), new XYZ(this.endConnector.Origin.X, this.endConnector.Origin.Y, 0.0));
			YJKLine hyline2 = new YJKLine(new XYZ(hypiping.StartConnector.Origin.X, hypiping.StartConnector.Origin.Y, 0.0), new XYZ(hypiping.endConnector.Origin.X, hypiping.endConnector.Origin.Y, 0.0));
			return hyline.GetXYDistance(hyline2.Line);
		}

		public double GetDPPipeDistance(T otherPiping)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			return hyline.GetDPLineDistance(hyline2.Line);
		}

		public XYZ GetXYVector(T otherPiping)
		{
			new XYZ(0.0, 0.0, 0.0);
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			return hyline.GetXYVector(hyline2.Line);
		}

		public XYZ GetVectorPoint(XYZ point)
		{
			new XYZ();
			return (this.GetLineProject(point) - point).Normalize();
		}

		public Curve GetGlobalEdge()
		{
			Curve result = null;
			Options options = new Options();
			options.ComputeReferences = true;
			foreach (GeometryObject geometryObject in new YJKElement(this.piping).GetGeometry(options))
			{
				if (geometryObject is Solid)
				{
					foreach (object obj in (geometryObject as Solid).Edges)
					{
						Edge edge = (Edge)obj;
						if (edge.AsCurve().Distance(this.globalPoint) < 0.0001)
						{
							result = edge.AsCurve();
							break;
						}
					}
				}
			}
			return result;
		}

		public double GetDuctWidthOrHeight(int widthOrHeight)
		{
			double result = -1.0;
			if (this.Shape == ConnectorSharp.Round)
			{
				result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble();
			}
			if (this.Shape == ConnectorSharp.Rect)
			{
				IList<Edge> ductEdges = UnifiedModified.GetDuctEdges(this.piping as Duct);
				XYZ xyz = this.startConnector.Connector.CoordinateSystem.BasisX;
				if (widthOrHeight != 0)
				{
					if (widthOrHeight == 1)
					{
						xyz = this.startConnector.Connector.CoordinateSystem.BasisY;
					}
				}
				else
				{
					xyz = this.startConnector.Connector.CoordinateSystem.BasisX;
				}
				foreach (YJKArchMethodLibrary.StructurePoleSuit.Edge edge in ductEdges)
				{
					if (!(edge == null))
					{
						IList<XYZ> list = edge.AsCurve().Tessellate();
						if (list[0].Subtract(list[1]).Normalize().IsAlmostEqualTo(xyz, 0.0001))
						{
							result = edge.ApproximateLength;
							break;
						}
					}
				}
			}
			return result;
		}

		public BetweenConnector GetConnectElement(T otherPiping)
		{
			BetweenConnector betweenConnector = null;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			if (this.startConnector.Connector.Shape != hypiping.StartConnector.Connector.Shape)
			{
				return null;
			}
			Element element = (this.GetConnectConnector(this.startConnector.Connector) == null) ? null : this.GetConnectConnector(this.startConnector.Connector).Owner;
			Element element2 = (this.GetConnectConnector(this.endConnector.Connector) == null) ? null : this.GetConnectConnector(this.endConnector.Connector).Owner;
			Element element3 = (hypiping.GetConnectConnector(hypiping.StartConnector.Connector) == null) ? null : hypiping.GetConnectConnector(hypiping.StartConnector.Connector).Owner;
			Element element4 = (hypiping.GetConnectConnector(hypiping.EndConnector.Connector) == null) ? null : hypiping.GetConnectConnector(hypiping.EndConnector.Connector).Owner;
			if (element != null && element3 != null && element.Id == element3.Id)
			{
				betweenConnector = new BetweenConnector();
				betweenConnector.Element = element;
				betweenConnector.StartConnector = this.startConnector.Connector;
				betweenConnector.EndConnector = hypiping.StartConnector.Connector;
			}
			else if (element != null && element4 != null && element.Id == element4.Id)
			{
				betweenConnector = new BetweenConnector();
				betweenConnector.Element = element;
				betweenConnector.StartConnector = this.startConnector.Connector;
				betweenConnector.EndConnector = hypiping.EndConnector.Connector;
			}
			else if (element2 != null && element3 != null && element2.Id == element3.Id)
			{
				betweenConnector = new BetweenConnector();
				betweenConnector.Element = element2;
				betweenConnector.StartConnector = this.endConnector.Connector;
				betweenConnector.EndConnector = hypiping.StartConnector.Connector;
			}
			else if (element2 != null && element4 != null && element2.Id == element4.Id)
			{
				betweenConnector = new BetweenConnector();
				betweenConnector.Element = element2;
				betweenConnector.StartConnector = this.endConnector.Connector;
				betweenConnector.EndConnector = hypiping.EndConnector.Connector;
			}
			return betweenConnector;
		}

		public XYZ GetGlobalOnCenterLinePoint(XYZ gPoint)
		{
			XYZ result = null;
			if (gPoint != null)
			{
				Curve locationCurve = this.GetLocationCurve();
				new IntersectionResult();
				result = locationCurve.Project(gPoint).XYZPoint;
			}
			return result;
		}

		public bool IsRect()
		{
			bool result = false;
			Parameter parameter = this.piping.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
			Parameter parameter2 = this.piping.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
			if (parameter2 != null && parameter != null)
			{
				result = true;
			}
			return result;
		}

		public bool Rotate90()
		{
			bool result = false;
			Autodesk.Revit.DB.Document document = this.piping.Document;
			Parameter parameter = this.piping.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
			Parameter parameter2 = this.piping.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
			if (parameter != null && parameter != null)
			{
				double num = parameter.AsDouble();
				double num2 = parameter2.AsDouble();
				parameter.Set(num2);
				parameter2.Set(num);
				document.Regenerate();
				result = true;
			}
			return result;
		}

		public Line GetPipingAxis()
		{
			return YJKLineEx.YJKGetBound(this.startConnector.Origin, this.endConnector.Origin);
		}

		public bool IsXAxis()
		{
			bool result = false;
			if ((this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(1.0, 0.0, 0.0)) || (this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(-1.0, 0.0, 0.0)))
			{
				result = true;
			}
			return result;
		}

		public bool IsYAxis()
		{
			bool result = false;
			if ((this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(0.0, 1.0, 0.0)) || (this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(0.0, -1.0, 0.0)))
			{
				result = true;
			}
			return result;
		}

		public bool IsZAxis()
		{
			bool result = false;
			if ((this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(0.0, 0.0, 1.0)) || (this.startConnector.Origin - this.endConnector.Origin).Normalize().IsAlmostEqualTo(new XYZ(0.0, 0.0, -1.0)))
			{
				result = true;
			}
			return result;
		}

		public PlanarFace GetDuctConnFace(XYZ pickPoint, double endPointDevision, ref int faceType, bool beCheckEnd = false)
		{
			PlanarFace result = null;
			if (!(this.piping is Duct))
			{
				return result;
			}
			IList<PlanarFace> ductSurface = UnifiedModified.GetDuctSurface(this.piping as Duct);
			double num = this.GetWeightOrDiameter() / 4.0;
			XYZ lineProject = this.GetLineProject(pickPoint);
			double num2 = this.StartConnector.Origin.DistanceTo(lineProject);
			double num3 = this.EndConnector.Origin.DistanceTo(lineProject);
			if (beCheckEnd)
			{
				if (num2 <= endPointDevision)
				{
					result = this.GetEndPlanarFace(ductSurface, this.StartConnector.Origin);
					faceType = 11;
				}
				else if (num3 <= endPointDevision)
				{
					result = this.GetEndPlanarFace(ductSurface, this.EndConnector.Origin);
					faceType = 11;
				}
				else if (this.GetProAndPickPointDis(lineProject, pickPoint) <= num)
				{
					result = this.GetDownPlanarFace(ductSurface);
					faceType = 22;
				}
				else
				{
					result = this.GetLeftOrRightPlanarFace(ductSurface, pickPoint);
					faceType = 33;
				}
			}
			else if (this.GetProAndPickPointDis(lineProject, pickPoint) <= num)
			{
				result = this.GetDownPlanarFace(ductSurface);
				faceType = 22;
			}
			else
			{
				result = this.GetLeftOrRightPlanarFace(ductSurface, pickPoint);
				faceType = 33;
			}
			return result;
		}

		private double GetProAndPickPointDis(XYZ proPoint, XYZ pickPoint)
		{
			pickPoint = new XYZ(pickPoint.X, pickPoint.Y, proPoint.Z);
			return proPoint.DistanceTo(pickPoint);
		}

		private PlanarFace GetLeftOrRightPlanarFace(IList<PlanarFace> ductFaces, XYZ pickPoint)
		{
			PlanarFace result = null;
			List<PlanarFace> list = new List<PlanarFace>();
			double num = 0.0001;
			XYZ xyz = new XYZ(0.0, 0.0, 1.0);
			XYZ xyz2 = new XYZ(this.StartConnector.Origin.X, this.StartConnector.Origin.Y, ductFaces.get_Item(0).Origin.Z);
			XYZ xyz3 = new XYZ(this.EndConnector.Origin.X, this.EndConnector.Origin.Y, ductFaces.get_Item(0).Origin.Z).Subtract(xyz2).Normalize();
			foreach (PlanarFace planarFace in ductFaces)
			{
				if (!planarFace.FaceNormal().IsAlmostEqualTo(xyz3, num) && !planarFace.FaceNormal().IsAlmostEqualTo(xyz3 * -1.0, num) && !planarFace.FaceNormal().IsAlmostEqualTo(xyz, num) && !planarFace.FaceNormal().IsAlmostEqualTo(-1.0 * xyz, num) && planarFace.Project(pickPoint) != null)
				{
					list.Add(planarFace);
				}
			}
			if (list.Count != 2)
			{
				return result;
			}
			double distance = list[0].Project(pickPoint).Distance;
			double distance2 = list[1].Project(pickPoint).Distance;
			result = ((distance < distance2) ? list[0] : list[1]);
			return result;
		}

		private PlanarFace GetEndPlanarFace(IList<PlanarFace> ductFaces, XYZ pickPoint)
		{
			PlanarFace result = null;
			List<PlanarFace> list = new List<PlanarFace>();
			XYZ xyz = new XYZ(this.StartConnector.Origin.X, this.StartConnector.Origin.Y, ductFaces.get_Item(0).Origin.Z);
			XYZ xyz2 = new XYZ(this.EndConnector.Origin.X, this.EndConnector.Origin.Y, ductFaces.get_Item(0).Origin.Z).Subtract(xyz).Normalize();
			foreach (PlanarFace planarFace in ductFaces)
			{
				XYZ origin = planarFace.Origin;
				if (planarFace.FaceNormal().IsAlmostEqualTo(xyz2, 0.001) || planarFace.FaceNormal().IsAlmostEqualTo(xyz2 * -1.0, 0.001))
				{
					list.Add(planarFace);
				}
			}
			if (list == null || list.Count != 2)
			{
				return result;
			}
			double distance = list[0].Project(pickPoint).Distance;
			double distance2 = list[1].Project(pickPoint).Distance;
			result = ((distance > distance2) ? list[1] : list[0]);
			return result;
		}

		private PlanarFace GetDownPlanarFace(IList<PlanarFace> ductFaces)
		{
			PlanarFace result = null;
			XYZ xyz = new XYZ(0.0, 0.0, -1.0);
			foreach (PlanarFace planarFace in ductFaces)
			{
				if (planarFace.FaceNormal().IsAlmostEqualTo(xyz, 0.001))
				{
					result = planarFace;
					break;
				}
			}
			return result;
		}

		public ElementId GetSystemElementId()
		{
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM);
			}
			else if (this.piping is Pipe)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
			}
			if (parameter != null)
			{
				return parameter.AsElementId();
			}
			return null;
		}

		public YJKLine GetXYProject()
		{
			XYZ xyz = new XYZ(this.startConnector.Origin.X, this.startConnector.Origin.Y, 0.0);
			XYZ xyz2 = new XYZ(this.endConnector.Origin.X, this.endConnector.Origin.Y, 0.0);
			YJKLine result = null;
			if (!xyz.IsAlmostEqualTo(xyz2))
			{
				result = new YJKLine(xyz, xyz2);
			}
			return result;
		}

		public List<XYZ> GetSlopPipeEndPoint()
		{
			List<XYZ> list = new List<XYZ>();
			if (this.StartConnector.Origin.Z < this.EndConnector.Origin.Z)
			{
				list.Insert(0, this.StartConnector.Origin);
				list.Insert(1, this.EndConnector.Origin);
			}
			else
			{
				list.Insert(0, this.EndConnector.Origin);
				list.Insert(1, this.StartConnector.Origin);
			}
			return list;
		}

		public int CheckPipingsPosition(T otherPiping)
		{
			int result = 0;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			XYZ xyz = this.IntersectionPoint(hypiping.Piping);
			double deviation;
			if (this.piping is Duct && this.piping.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM) != null)
			{
				deviation = this.piping.Diameter;
			}
			else if (this.piping is Pipe && this.piping.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM) != null)
			{
				deviation = this.piping.Diameter;
			}
			else
			{
				deviation = (this.piping.Width + this.piping.Height) / 2.0;
			}
			if (this.IsPipingOnLine(hypiping.Piping))
			{
				result = 10;
			}
			else if (this.IsParallel(hypiping.Piping))
			{
				if (Math.Abs(this.startConnector.Origin.Z - this.endConnector.Origin.Z) < 0.0001 && Math.Abs(hypiping.StartConnector.Origin.Z - hypiping.EndConnector.Origin.Z) < 0.0001 && Math.Abs(this.startConnector.Origin.Z - hypiping.StartConnector.Origin.Z) < 0.0001)
				{
					result = 11;
				}
				else if (this.GetXYProject() == null || hypiping.GetXYProject() == null)
				{
					if (this.GetRiserPosition(hypiping) == 0)
					{
						result = 21;
					}
					else
					{
						result = 21;
					}
				}
				else if (this.GetXYProject().IsLineOnLine(hypiping.GetXYProject().Line))
				{
					result = 11;
				}
				else
				{
					result = 21;
				}
			}
			else if (xyz != null)
			{
				if (this.IsPointOnPipingCurve(xyz, deviation) && hypiping.IsPointOnPipingCurve(xyz, deviation))
				{
					result = 14;
				}
				else if (this.IsPointOnPipingCurve(xyz, deviation) || hypiping.IsPointOnPipingCurve(xyz, deviation))
				{
					result = 13;
				}
				else
				{
					result = 12;
				}
			}
			else
			{
				XYZ defferentPlaneInstersection = this.GetDefferentPlaneInstersection(hypiping.Piping);
				XYZ defferentPlaneInstersection2 = hypiping.GetDefferentPlaneInstersection(this.piping);
				if (defferentPlaneInstersection != null && defferentPlaneInstersection2 != null)
				{
					if (this.IsPointOnPipingCurve(defferentPlaneInstersection, deviation) && hypiping.IsPointOnPipingCurve(defferentPlaneInstersection2, deviation))
					{
						result = 24;
					}
					else if (this.IsPointOnPipingCurve(defferentPlaneInstersection, deviation) || hypiping.IsPointOnPipingCurve(defferentPlaneInstersection2, deviation))
					{
						result = 23;
					}
					else
					{
						result = 22;
					}
				}
			}
			return result;
		}

		private int GetRiserPosition(YJKPiping<T> hypiping)
		{
			double z;
			double z2;
			if (this.startConnector.Origin.Z > this.endConnector.Origin.Z)
			{
				z = this.endConnector.Origin.Z;
				z2 = this.startConnector.Origin.Z;
			}
			else
			{
				z2 = this.endConnector.Origin.Z;
				z = this.startConnector.Origin.Z;
			}
			double z3;
			double z4;
			if (hypiping.StartConnector.Origin.Z > hypiping.EndConnector.Origin.Z)
			{
				z3 = hypiping.EndConnector.Origin.Z;
				z4 = hypiping.StartConnector.Origin.Z;
			}
			else
			{
				z4 = hypiping.EndConnector.Origin.Z;
				z3 = hypiping.StartConnector.Origin.Z;
			}
			int result;
			if (z > z4)
			{
				result = 0;
			}
			else if (z2 < z3)
			{
				result = 0;
			}
			else
			{
				result = 1;
			}
			return result;
		}

		public XYZ GetDefferentPlaneInstersection(T otherPiping)
		{
			XYZ result = null;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			XYZ project = this.GetProject(hypiping.StartConnector.Origin, true);
			XYZ project2 = this.GetProject(hypiping.EndConnector.Origin, true);
			if (project.IsAlmostEqualTo(project2) && !this.IsParallel(otherPiping))
			{
				result = project;
			}
			return result;
		}

		public bool IsSamePlan(T otherPiping)
		{
			bool result = false;
			Curve curve = (otherPiping.Location as LocationCurve).Curve;
			if (Math.Abs(this.startConnector.Origin.Z - this.endConnector.Origin.Z) < 0.0001 && Math.Abs(this.startConnector.Origin.Z - curve.GetEndPoint(0).Z) < 0.0001 && Math.Abs(curve.GetEndPoint(0).Z - curve.GetEndPoint(1).Z) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public IList<XYZ> GetAppAndEndPoint(T otherPiping)
		{
			IList<XYZ> list = new List<XYZ>();
			bool flag = false;
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			if (this.GetDiameter() > hypiping.GetDiameter())
			{
				if (!hypiping.StartConnector.Connector.IsConnected)
				{
					XYZ xyz = hypiping.StartConnector.Origin - hypiping.GetXYVector(this.piping) * hypiping.GetXYDistance(this.piping);
					XYZ xyz2 = new XYZ(xyz.X, xyz.Y, this.startConnector.Origin.Z);
					XYZ project = this.GetProject(hypiping.startConnector.Origin);
					if (project != null && xyz2.IsAlmostEqualTo(project))
					{
						list.Add(hypiping.StartConnector.Origin);
						list.Add(project);
						flag = true;
					}
				}
				if (!hypiping.EndConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz3 = hypiping.EndConnector.Origin - hypiping.GetXYVector(this.piping) * hypiping.GetXYDistance(this.piping);
					XYZ xyz4 = new XYZ(xyz3.X, xyz3.Y, this.endConnector.Origin.Z);
					XYZ project2 = this.GetProject(hypiping.EndConnector.Origin);
					if (project2 != null && xyz4.IsAlmostEqualTo(project2))
					{
						list.Add(hypiping.EndConnector.Origin);
						list.Add(project2);
						flag = true;
					}
				}
				if (!this.startConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz5 = this.startConnector.Origin - this.GetXYVector(hypiping.Piping) * this.GetXYDistance(hypiping.Piping);
					XYZ xyz6 = new XYZ(xyz5.X, xyz5.Y, hypiping.StartConnector.Origin.Z);
					XYZ project3 = hypiping.GetProject(this.StartConnector.Origin);
					if (project3 != null && xyz6.IsAlmostEqualTo(project3))
					{
						list.Add(this.startConnector.Origin);
						list.Add(project3);
						flag = true;
					}
				}
				if (!this.endConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz7 = this.endConnector.Origin - this.GetXYVector(hypiping.Piping) * this.GetXYDistance(hypiping.Piping);
					XYZ xyz8 = new XYZ(xyz7.X, xyz7.Y, hypiping.EndConnector.Origin.Z);
					XYZ project4 = hypiping.GetProject(this.endConnector.Origin);
					if (project4 != null && xyz8.IsAlmostEqualTo(project4))
					{
						list.Add(this.endConnector.Origin);
						list.Add(project4);
					}
				}
			}
			else
			{
				if (!this.startConnector.Connector.IsConnected)
				{
					XYZ xyz9 = this.startConnector.Origin - this.GetXYVector(hypiping.Piping) * this.GetXYDistance(hypiping.Piping);
					XYZ xyz10 = new XYZ(xyz9.X, xyz9.Y, hypiping.startConnector.Origin.Z);
					XYZ project5 = hypiping.GetProject(this.startConnector.Origin);
					if (project5 != null && xyz10.IsAlmostEqualTo(project5))
					{
						list.Add(this.startConnector.Origin);
						list.Add(project5);
						flag = true;
					}
				}
				if (!this.endConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz11 = this.endConnector.Origin - this.GetXYVector(hypiping.Piping) * this.GetXYDistance(hypiping.Piping);
					XYZ xyz12 = new XYZ(xyz11.X, xyz11.Y, hypiping.EndConnector.Origin.Z);
					XYZ project6 = hypiping.GetProject(this.endConnector.Origin);
					if (project6 != null && xyz12.IsAlmostEqualTo(project6))
					{
						list.Add(this.endConnector.Origin);
						list.Add(project6);
						flag = true;
					}
				}
				if (!hypiping.StartConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz13 = hypiping.StartConnector.Origin - hypiping.GetXYVector(this.piping) * hypiping.GetXYDistance(this.piping);
					XYZ xyz14 = new XYZ(xyz13.X, xyz13.Y, this.startConnector.Origin.Z);
					XYZ project7 = this.GetProject(hypiping.startConnector.Origin);
					if (project7 != null && xyz14.IsAlmostEqualTo(project7))
					{
						list.Add(hypiping.StartConnector.Origin);
						list.Add(project7);
						flag = true;
					}
				}
				if (!hypiping.EndConnector.Connector.IsConnected && !flag)
				{
					XYZ xyz15 = hypiping.EndConnector.Origin - hypiping.GetXYVector(this.piping) * hypiping.GetXYDistance(this.piping);
					XYZ xyz16 = new XYZ(xyz15.X, xyz15.Y, this.endConnector.Origin.Z);
					XYZ project8 = this.GetProject(hypiping.EndConnector.Origin);
					if (project8 != null && xyz16.IsAlmostEqualTo(project8))
					{
						list.Add(hypiping.EndConnector.Origin);
						list.Add(project8);
					}
				}
			}
			return list;
		}

		public XYZ GetProject(XYZ point)
		{
			return new YJKLine(this.startConnector.Origin, this.endConnector.Origin).GetProject(point);
		}

		public XYZ GetProjectPoint(XYZ point, bool unBound = true)
		{
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			if (unBound)
			{
				hyline.MakeUnBound();
			}
			return hyline.GetProject(point);
		}

		public XYZ GetProject(FamilyInstance fi)
		{
			XYZ loctaionPoint = YJKRevitTools.GetLoctaionPoint(fi);
			return this.GetProject(loctaionPoint);
		}

		public XYZ GetProject(XYZ point, bool unBound)
		{
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			hyline.MakeUnBound();
			return hyline.GetProject(point);
		}

		public XYZ GetProject(FamilyInstance fi, bool unBound)
		{
			XYZ loctaionPoint = YJKRevitTools.GetLoctaionPoint(fi);
			return this.GetProject(loctaionPoint, true);
		}

		public XYZ GetLineProject(XYZ point)
		{
			YJKLine hyline = new YJKLine(this.startConnector.Origin, this.endConnector.Origin);
			hyline.MakeUnBound();
			return hyline.GetProject(point);
		}

		public double GetOuterDiameter()
		{
			Parameter parameter = null;
			double result = 0.0;
			if (this.piping is Pipe)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER);
			}
			if (parameter != null)
			{
				result = parameter.AsDouble();
			}
			return result;
		}

		public double GetDiameter()
		{
			Parameter parameter = null;
			double result = 0.0;
			if (this.piping is Duct)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_HYDRAULIC_DIAMETER_PARAM);
			}
			else if (this.piping is Pipe)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
			}
			if (parameter != null)
			{
				result = parameter.AsDouble();
			}
			return result;
		}

		public bool SetDiameter(double diameter)
		{
			Parameter parameter = null;
			bool result = false;
			if (this.piping is Duct)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_HYDRAULIC_DIAMETER_PARAM);
			}
			else if (this.piping is Pipe)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
			}
			if (parameter != null && parameter.Set(diameter / 304.8))
			{
				result = true;
			}
			return result;
		}

		public bool SetLevel(ElementId elementId)
		{
			Parameter parameter = null;
			bool result = false;
			if (this.piping is Duct)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
			}
			else if (this.piping is Pipe)
			{
				parameter = this.piping.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
			}
			if (parameter != null && parameter.Set(elementId))
			{
				result = true;
			}
			return result;
		}

		public YJKPipingSystemType GetConnectorPipingSystemType()
		{
			YJKPipingSystemType result = default(YJKPipingSystemType);
			if (this.piping is Duct)
			{
				result.ductSystemType = this.startConnector.Connector.DuctSystemType;
			}
			else if (this.piping is Pipe)
			{
				result.pipeSystemType = this.startConnector.Connector.PipeSystemType;
			}
			return result;
		}

		public bool Combine(T otherPiping)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				Autodesk.Revit.DB.Document document = this.piping.Document;
				IList<Connector> list = new List<Connector>();
				list = this.GetAppropriateConnector(otherPiping);
				if (list.Count > 1 && (list[0].IsConnected || list[1].IsConnected))
				{
					throw new Exception("接头已经连接");
				}
				subTransaction = new SubTransaction(document);
				subTransaction.Start();
				bool flag = false;
				XYZ xyz = null;
				XYZ xyz2 = null;
				List<Connector> distanceConnector = this.GetDistanceConnector(otherPiping);
				List<Connector> list2 = new List<Connector>();
				foreach (Connector connector in distanceConnector)
				{
					if (connector != null && connector.IsConnected)
					{
						Connector connectConnector = this.GetConnectConnector(connector);
						list2.Add(connectConnector);
						connector.DisconnectFrom(connectConnector);
					}
				}
				if (distanceConnector != null && distanceConnector.Count > 1)
				{
					xyz = distanceConnector[0].Origin;
					xyz2 = distanceConnector[1].Origin;
				}
				if (xyz != null && xyz2 != null)
				{
					Line curve = YJKLineEx.YJKGetBound(xyz, xyz2);
					(this.piping.Location as LocationCurve).Curve = curve;
					document.Regenerate();
					this.ChangePiping(this.piping);
					foreach (Connector connector2 in list2)
					{
						if (connector2 != null)
						{
							if (connector2.Origin.IsAlmostEqualTo(this.startConnector.Origin))
							{
								this.startConnector.Connector.ConnectTo(connector2);
							}
							else if (connector2.Origin.IsAlmostEqualTo(this.endConnector.Origin))
							{
								this.endConnector.Connector.ConnectTo(connector2);
							}
						}
					}
					flag = true;
					document.DeleteElement(otherPiping);
					document.Regenerate();
				}
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (subTransaction != null && subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}

		public List<Connector> GetDistanceConnector(T otherPiping)
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(otherPiping);
			List<Connector> list = new List<Connector>();
			Connector connector;
			Connector connector2;
			if (this.startConnector.Origin.DistanceTo(hypiping.StartConnector.Origin) > this.startConnector.Origin.DistanceTo(hypiping.EndConnector.Origin))
			{
				if (this.startConnector.Origin.DistanceTo(hypiping.StartConnector.Origin) > this.endConnector.Origin.DistanceTo(hypiping.StartConnector.Origin))
				{
					connector = this.startConnector.Connector;
					connector2 = hypiping.StartConnector.Connector;
				}
				else
				{
					connector = this.endConnector.Connector;
					connector2 = hypiping.StartConnector.Connector;
				}
			}
			else if (this.startConnector.Origin.DistanceTo(hypiping.EndConnector.Origin) > this.endConnector.Origin.DistanceTo(hypiping.EndConnector.Origin))
			{
				connector = this.startConnector.Connector;
				connector2 = hypiping.EndConnector.Connector;
			}
			else
			{
				connector = this.endConnector.Connector;
				connector2 = hypiping.EndConnector.Connector;
			}
			if (connector != null && connector2 != null)
			{
				list.Add(connector);
				list.Add(connector2);
			}
			return list;
		}

		public Connector GetDistanceConnector(XYZ xyz)
		{
			if (this.startConnector.Origin.DistanceTo(xyz) <= this.endConnector.Origin.DistanceTo(xyz))
			{
				return this.endConnector.Connector;
			}
			return this.startConnector.Connector;
		}

		public bool ChangeFirstTee(FamilySymbol fs)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.DuctSetFittingTee((this.piping as Duct).DuctType, fs);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TEE_PARAM);
			}
			if (parameter != null && parameter.Set(fs.Id))
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTee(string fsName)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (UnifiedModified.CheckDuctSetFittingTee(this.piping as Duct, fsName))
				{
					return true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TEE_PARAM);
			}
			if (parameter != null && parameter.Definition.Name == fsName)
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTeeIsNull()
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (!UnifiedModified.CheckDuctSetFittingTee(this.piping as Duct, ""))
				{
					result = true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TEE_PARAM);
			}
			if (parameter != null && parameter.Definition.Name != "")
			{
				result = true;
			}
			return result;
		}

		public bool ChangeFirstElbow(FamilySymbol fs)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.DuctSetFittingElbow((this.piping as Duct).DuctType, fs);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_ELBOW_PARAM);
			}
			if (parameter != null && parameter.Set(fs.Id))
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstElbow(string fsName)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.CheckDuctSetFittingElbow(this.piping as Duct, fsName);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_ELBOW_PARAM);
			}
			if (parameter != null && parameter.Definition.Name == fsName)
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstElbowIsNull()
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (!UnifiedModified.CheckDuctSetFittingElbow(this.piping as Duct, ""))
				{
					return true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_ELBOW_PARAM);
			}
			if (parameter != null && parameter.Definition.Name != "")
			{
				result = true;
			}
			return result;
		}

		public bool ChangeFirstCross(FamilySymbol fs)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.DuctSetFittingCross((this.piping as Duct).DuctType, fs);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_CROSS_PARAM);
			}
			if (parameter != null && parameter.Set(fs.Id))
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstCross(string fsName)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.CheckDuctSetFittingCross(this.piping as Duct, fsName);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_CROSS_PARAM);
			}
			if (parameter != null && parameter.Definition.Name == fsName)
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstCrossIsNull()
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (!UnifiedModified.CheckDuctSetFittingCross(this.piping as Duct, ""))
				{
					return true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_CROSS_PARAM);
			}
			if (parameter != null && parameter.Definition.Name != "")
			{
				result = true;
			}
			return result;
		}

		public bool ChangeFirstTransition(FamilySymbol fs)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.DuctSetFittingTrans((this.piping as Duct).DuctType, fs);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TRANSITION_PARAM);
			}
			if (parameter != null && parameter.Set(fs.Id))
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTransition(string fsName)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.CheckDuctSetFittingTrans(this.piping as Duct, fsName);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TRANSITION_PARAM);
			}
			if (parameter != null && parameter.Definition.Name == fsName)
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTransitionIsNull()
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (!UnifiedModified.CheckDuctSetFittingTrans(this.piping as Duct, ""))
				{
					return true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TRANSITION_PARAM);
			}
			if (parameter != null && parameter.Definition.Name != "")
			{
				result = true;
			}
			return result;
		}

		public bool ChangeFirstTakeOff(FamilySymbol fs)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.DuctSetFittingTakeOff((this.piping as Duct).DuctType, fs);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TAKEOFF_PARAM);
			}
			if (parameter != null && parameter.Set(fs.Id))
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTakeOff(string fsName)
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				return UnifiedModified.CheckDuctSetFittingTakeOff(this.piping as Duct, fsName);
			}
			if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TAKEOFF_PARAM);
			}
			if (parameter != null && parameter.Definition.Name == fsName)
			{
				result = true;
			}
			return result;
		}

		public bool CheckFirstTakeOffIsNull()
		{
			bool result = false;
			Parameter parameter = null;
			if (this.piping is Duct)
			{
				if (!UnifiedModified.CheckDuctSetFittingTakeOff(this.piping as Duct, ""))
				{
					return true;
				}
			}
			else if (this.piping is Pipe)
			{
				parameter = (this.piping as Pipe).PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TAKEOFF_PARAM);
			}
			if (parameter != null && parameter.Definition.Name != "")
			{
				result = true;
			}
			return result;
		}

		public bool ChangeFirstTYDF(FamilySymbol fs)
		{
			return this.piping is Duct && UnifiedModified.DuctSetFittingTYDF((this.piping as Duct).DuctType, fs);
		}

		public bool CheckFirstTYDF(string fsName)
		{
			return this.piping is Duct && UnifiedModified.CheckDuctSetFittingTYDF(this.piping as Duct, fsName);
		}

		public bool CheckFirstTYDFIsNull()
		{
			return this.piping is Duct && !UnifiedModified.CheckDuctSetFittingTYDF(this.piping as Duct, "");
		}

		public double GetOffSet()
		{
			return this.piping.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).AsDouble();
		}

		public double GetHeightOrDiameter()
		{
			double result = 0.0;
			if (this.piping is Duct)
			{
				if ((this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM) != null)
				{
					result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM).AsDouble();
				}
				else
				{
					result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble();
				}
			}
			else if (this.piping is Pipe)
			{
				result = (this.piping as Pipe).get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
			}
			return result;
		}

		public Line getPipingReferenceLine()
		{
			Line result = null;
			if (this.globalPoint != null)
			{
				XYZ xyz = new XYZ(this.globalPoint.X, this.globalPoint.Y, 0.0);
				double num = 0.0;
				Line curve = (this.piping.Location as LocationCurve).Curve as Line;
				XYZ xyz2 = new XYZ(curve.GetEndPoint(0).X, curve.GetEndPoint(0).Y, 0.0);
				XYZ xyz3 = new XYZ(curve.GetEndPoint(1).X, curve.GetEndPoint(1).Y, 0.0);
				Line line = new YJKLine(xyz2, xyz3).Line;
				XYZ xyz4 = (xyz2 - xyz3).Normalize();
				XYZ project = new YJKLine(line).GetProject(xyz);
				XYZ xyz5 = (xyz - project).Normalize();
				if (this.piping is Duct)
				{
					if ((this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM) != null)
					{
						num = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble();
					}
					else
					{
						num = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble();
					}
				}
				else if (this.piping is Pipe)
				{
					num = (this.piping as Pipe).get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER).AsDouble();
				}
				XYZ xyz6 = project + num / 2.0 * xyz5;
				result = new YJKLine(xyz6, xyz6 + 1.0 * xyz4).Line;
			}
			return result;
		}

		public double GetWeightOrDiameter()
		{
			double result = 0.0;
			if (this.piping is Duct)
			{
				if ((this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM) != null)
				{
					result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM).AsDouble();
				}
				else
				{
					result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsDouble();
				}
			}
			else if (this.piping is Pipe)
			{
				result = (this.piping as Pipe).get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble();
			}
			return result;
		}

		public double GetDuctEQDiameter()
		{
			double result = 0.0;
			if (this.piping is Duct && (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_EQ_DIAMETER_PARAM) != null)
			{
				result = (this.piping as Duct).get_Parameter(BuiltInParameter.RBS_EQ_DIAMETER_PARAM).AsDouble();
			}
			return result;
		}

		public bool SetOffSet(double offSet)
		{
			return this.piping.get_Parameter(BuiltInParameter.RBS_OFFSET_PARAM).Set(offSet);
		}

		public double GetXAxisAngle()
		{
			XYZ xyz;
			if (Math.Abs(this.startConnector.Origin.Y - this.endConnector.Origin.Y) > 0.0001)
			{
				if (this.startConnector.Origin.Y > this.endConnector.Origin.Y)
				{
					xyz = this.endConnector.Origin - this.startConnector.Origin;
				}
				else
				{
					xyz = this.startConnector.Origin - this.endConnector.Origin;
				}
			}
			else
			{
				xyz = new XYZ(1.0, 0.0, 0.0);
			}
			return xyz.AngleTo(new XYZ(1.0, 0.0, 0.0));
		}

		public void Rotate(double angle)
		{
			if (Math.Abs(this.startConnector.Origin.Z - this.endConnector.Origin.Z) > 0.0001)
			{
				Autodesk.Revit.DB.Document document = this.piping.Document;
				Line line;
				if (this.startConnector.Origin.Z < this.endConnector.Origin.Z)
				{
					line = YJKLineEx.YJKGetBound(this.startConnector.Origin, this.endConnector.Origin);
				}
				else
				{
					line = YJKLineEx.YJKGetBound(this.endConnector.Origin, this.startConnector.Origin);
				}
				line.MakeUnbound();
				ElementTransformUtils.RotateElement(document, this.piping.Id, line, angle);
			}
		}

		public bool Extend(Connector conn)
		{
			if (conn == null)
			{
				return false;
			}
			double num = this.startConnector.Origin.DistanceTo(conn.Origin);
			double num2 = this.endConnector.Origin.DistanceTo(conn.Origin);
			XYZ origin;
			Connector connectConnector;
			if (num > num2)
			{
				origin = this.startConnector.Origin;
				connectConnector = this.GetConnectConnector(this.startConnector.Connector);
				if (connectConnector != null)
				{
					connectConnector.DisconnectFrom(this.startConnector.Connector);
				}
			}
			else
			{
				origin = this.endConnector.Origin;
				connectConnector = this.GetConnectConnector(this.endConnector.Connector);
				if (connectConnector != null)
				{
					connectConnector.DisconnectFrom(this.endConnector.Connector);
				}
			}
			if (!origin.IsAlmostEqualTo(conn.Origin))
			{
				LocationCurve locationCurve = this.piping.Location as LocationCurve;
				Line curve = YJKLineEx.YJKGetBound(origin, conn.Origin);
				locationCurve.Curve = curve;
				conn.Owner.Document.Regenerate();
				this.ChangePiping(this.piping);
			}
			if (connectConnector != null)
			{
				if (this.startConnector.Origin.IsAlmostEqualTo(connectConnector.Origin))
				{
					this.startConnector.Connector.ConnectTo(connectConnector);
				}
				else
				{
					this.endConnector.Connector.ConnectTo(connectConnector);
				}
			}
			if (this.startConnector.Origin.IsAlmostEqualTo(conn.Origin))
			{
				this.startConnector.Connector.ConnectTo(conn);
			}
			else
			{
				this.endConnector.Connector.ConnectTo(conn);
			}
			return true;
		}

		public T Extend(XYZ startP, XYZ endP)
		{
			Connector connector = null;
			Connector connector2 = null;
			double num = 0.0001;
			if (this.startConnector.Connector.IsConnected && (this.startConnector.Origin.IsAlmostEqualTo(startP, num) || this.startConnector.Origin.IsAlmostEqualTo(endP, num)))
			{
				connector = this.GetConnectConnector(this.startConnector.Connector);
				this.startConnector.Connector.DisconnectFrom(connector);
			}
			if (this.endConnector.Connector.IsConnected && (this.endConnector.Origin.IsAlmostEqualTo(startP, num) || this.endConnector.Origin.IsAlmostEqualTo(endP, num)))
			{
				connector2 = this.GetConnectConnector(this.endConnector.Connector);
				this.endConnector.Connector.DisconnectFrom(connector2);
			}
			this.piping.Document.Regenerate();
			Line curve = YJKLineEx.YJKGetBound(startP, endP);
			(this.piping.Location as LocationCurve).Curve = curve;
			this.piping.Document.Regenerate();
			this.ChangePiping(this.piping);
			if (connector != null)
			{
				this.ConnectCloseConnector(connector);
			}
			if (connector2 != null)
			{
				this.ConnectCloseConnector(connector2);
			}
			return this.piping;
		}

		public void ConnectCloseConnector(Connector conn)
		{
			if (conn != null)
			{
				double num = 0.0001;
				if (this.startConnector.Origin.IsAlmostEqualTo(conn.Origin, num) && !this.startConnector.Connector.IsConnected)
				{
					this.startConnector.Connector.ConnectTo(conn);
					return;
				}
				if (this.endConnector.Origin.IsAlmostEqualTo(conn.Origin, num) && !this.endConnector.Connector.IsConnected)
				{
					this.endConnector.Connector.ConnectTo(conn);
				}
			}
		}

		public XYZ GetXYVectorPointToPiping(XYZ point)
		{
			XYZ result = null;
			if (Math.Abs(this.startConnector.Origin.Z - this.endConnector.Origin.Z) < 0.001)
			{
				YJKLine xyproject = this.GetXYProject();
				XYZ xyz = new XYZ(point.X, point.Y, 0.0);
				xyproject.MakeUnBound();
				result = (xyproject.GetProject(xyz) - xyz).Normalize();
			}
			return result;
		}

		public XYZ GetDistancePoint(XYZ point)
		{
			XYZ result = null;
			if (point != null)
			{
				if (point.DistanceTo(this.startConnector.Origin) < point.DistanceTo(this.endConnector.Origin))
				{
					result = this.endConnector.Origin;
				}
				else
				{
					result = this.startConnector.Origin;
				}
			}
			return result;
		}

		private T piping;

		private HYConnector startConnector;

		private HYConnector endConnector;

		private bool isSeparate;

		private XYZ globalPoint;

		private IList<Connector> sideConnector;

		private ConnectorProfileType shape = ConnectorSharp.Rect;

		private int pipingPositionType;
	}
}
